package me.sdevil507.biz.common.sysdict.controller;

/**
 * @program: tips_back_end
 * @description:
 * @author: kzl
 * @create: 2020-06-29 11:53
 **/

import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.sysdict.dto.SysDictParamsDTO;
import me.sdevil507.biz.common.sysdict.po.SysDict;
import me.sdevil507.biz.common.sysdict.service.SysdictService;
import me.sdevil507.supports.jpa.PageResultDTO;
import me.sdevil507.supports.result.ApiResultDTO;
import me.sdevil507.supports.result.ApiResultGenerator;
import me.sdevil507.supports.status.ApiStatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/common/sysdict/")
@Slf4j
public class SysDictController {

    @Autowired
    private SysdictService sysdictService;

    @PostMapping("/v1/getByTypeKey")
    public List<SysDict> getAll(@RequestBody SysDict sysDict) {
        return sysdictService.findByTypeKey(sysDict.getTypeKey());
    }

    @PostMapping("/v1/create")
    @Transactional(rollbackFor = Exception.class)
    public ApiResultDTO create(@RequestBody SysDict sysDict) {
        ApiResultDTO apiResultDTO;
        // 执行新增
        try {
            List<SysDict> sysDictList= sysdictService.findExistsByName(sysDict.getDname(),sysDict.getParentId(),sysDict.getId());
            if(sysDictList.size()>0){
                apiResultDTO = ApiResultGenerator.create(ApiStatusCode.FRUIT_NAME_EXISTED.getCode(), ApiStatusCode.SYSDICT_NAME_EXISTED.getDescription());
                return  apiResultDTO;
            }

             sysDictList= sysdictService.findExistsByCode(sysDict.getDcode(),sysDict.getParentId(),sysDict.getId());
            if(sysDictList.size()>0){
                apiResultDTO = ApiResultGenerator.create(ApiStatusCode.FRUIT_NAME_EXISTED.getCode(), ApiStatusCode.SYSDICT_CODE_EXISTED.getDescription());
                return  apiResultDTO;
            }

            sysdictService.create(sysDict);

            //新增字典表的子集
            if(sysDict.getParentId() != 1){
                //删除原有的字典表redis缓存
                sysdictService.deleteByTypeKey(sysDict.getTypeKey());
                //重新设置缓存值
                sysdictService.findByTypeKey(sysDict.getTypeKey());
            }

            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
        } catch (Exception e) {
            //事务回滚
            log.error("添加字典表失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SYSDICT_CREATE_FAILED.getCode(), ApiStatusCode.SYSDICT_CREATE_FAILED.getDescription());
        }
        return apiResultDTO;
    }


    /**
     * 删除字典
     * @param sysDict 注册入参dto
     * @return 执行反馈
     */
    @PostMapping("/v1/delete")
    @Transactional(rollbackFor = Exception.class)
    public ApiResultDTO deleteFruit(@RequestBody SysDict sysDict) {
        ApiResultDTO apiResultDTO;
        // 执行逻辑删除
        try {
            sysDict = sysdictService.findOneById(sysDict.getId());

            sysdictService.delete(sysDict);

            //删除的是字典表的子集
            if(sysDict.getParentId() != 1){
                //删除原有的字典表redis缓存
                sysdictService.deleteByTypeKey(sysDict.getTypeKey());
                //重新设置缓存值
                sysdictService.findByTypeKey(sysDict.getTypeKey());
            }

            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SUCCESS.getCode(), ApiStatusCode.SUCCESS.getDescription());
        } catch (Exception e) {
            //事务回滚
            log.error("删除字典失败:"+sysDict.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            apiResultDTO = ApiResultGenerator.create(ApiStatusCode.SYSDICT_DEL_FAILED.getCode(), ApiStatusCode.SYSDICT_DEL_FAILED.getDescription());
        }
        return apiResultDTO;
    }


    @PostMapping("/v1/readAllByPage")
    public ApiResultDTO getAllByPage(@RequestBody SysDictParamsDTO sysDIctParamsDTO) {
        ApiResultDTO apiResultDto;
        try {
            Page<SysDict> pagePos = sysdictService.readAllByPage(sysDIctParamsDTO.getSearchDto(), sysDIctParamsDTO.getPageDto(), sysDIctParamsDTO.getSortDto());
            PageResultDTO<SysDict> pageResultDto =  new PageResultDTO<>();
            pageResultDto.setTotal(pagePos.getTotalElements());
            pageResultDto.setPages(pagePos.getTotalPages());
            pageResultDto.setRecords(pagePos.getContent());
            apiResultDto = ApiResultGenerator.create("0", "分页数据获取成功!", pageResultDto);
        } catch (Exception e) {
            log.error("分页数据获取失败:", e);
            apiResultDto = ApiResultGenerator.create("-1", "分页数据获取失败!");
        }
        return apiResultDto;
    }


    @PostMapping("/v1/readAll")
    public ApiResultDTO getAll(@RequestBody SysDictParamsDTO sysDIctParamsDTO) {
        ApiResultDTO apiResultDto;
        try {
            List<SysDict> list = sysdictService.readAll(sysDIctParamsDTO.getSearchDto(), sysDIctParamsDTO.getSortDto());
            apiResultDto = ApiResultGenerator.create("0", "获取信息列表成功!", list);
        } catch (Exception e) {
            log.error("获取信息列表失败:", e);
            apiResultDto = ApiResultGenerator.create("-1", "获取信息列表失败!");
        }
        return apiResultDto;
    }

    /**
     * 获取所有父级字典
     * @return 执行反馈
     */
    @PostMapping("/v1/getAllParent")
    public ApiResultDTO getAllParent() {
        ApiResultDTO apiResultDto;
        try {
            //查找根节点
            List<SysDict> treeLists=new ArrayList<>();
            SysDict sysDict=sysdictService.findOneById(new Long(1));
            treeLists.add(sysDict);
            getChildren(sysDict);
            PageResultDTO<SysDict> pageResultDto =  new PageResultDTO<>();
            pageResultDto.setRecords(treeLists);
            apiResultDto = ApiResultGenerator.create("0", "获取信息列表成功!", pageResultDto);
        } catch (Exception e) {
            log.error("获取信息列表失败:", e);
            apiResultDto = ApiResultGenerator.create("-1", "获取信息列表失败!");
        }
        return apiResultDto;
    }

    private void getChildren(SysDict sysDict) {
        //组装查询条件
        SysDict searchDTO = new SysDict();
        searchDTO.setParentId(sysDict.getId());
        List<SysDict> list = sysdictService.readAll(searchDTO,null);
        if(null!=list && list.size()>0){
            for(SysDict sys:list){
                getChildren(sys);
            }
        }
        sysDict.setChildren(list);
    }


    /**
     * 获取根据dcode获取父级完整字典
     * @return 执行反馈
     */
    @PostMapping("/v1/getParentTree")
    public ApiResultDTO getParentTree(@RequestBody SysDict sysDict) {
        ApiResultDTO apiResultDto;
        //查找根节点
        List<SysDict> treeLists=new ArrayList<>();
        try {
            //获取最顶层的父级（排序系统默认的父级）
            SysDict parentSysDict= getParentSysDict(sysDict);
            treeLists.add(parentSysDict);
            PageResultDTO<SysDict> pageResultDto =  new PageResultDTO<>();
            pageResultDto.setRecords(treeLists);
            apiResultDto = ApiResultGenerator.create("0", "获取信息列表成功!", pageResultDto);
        } catch (Exception e) {
            log.error("获取信息列表失败:", e);
            apiResultDto = ApiResultGenerator.create("-1", "获取信息列表失败!");
        }
        return apiResultDto;
    }

    private SysDict getParentSysDict(SysDict sysDict) {
        sysDict = sysdictService.findOneByCode(sysDict.getTypeKey());
        if (1!=(sysDict.getParentId())) {
            sysDict= getParentSysDict(sysDict);
        }
        return sysDict;
    }

}
